package ru.lukyanets.transmission.client.ui.control;

import javafx.beans.property.IntegerProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ObjectPropertyBase;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.WritableValue;
import javafx.css.StyleableProperty;
import javafx.geometry.Orientation;
import javafx.scene.AccessibleAttribute;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import ru.lukyanets.transmission.client.ui.control.skin.PiecesIndicatorSkin;

import java.util.BitSet;

/**
 * Represents bar indicator of pieces completion
 *
 * @author Sergey Lukyanets
 */
public class PiecesIndicator extends Control {
    /**
     * Initialize the style class to 'pieces-indicator'.
     * <p>
     * This is the selector class from which CSS can be used to style
     * this control.
     */
    private static final String DEFAULT_STYLE_CLASS = "pieces-indicator";

    public IntegerProperty countProperty = new SimpleIntegerProperty(0);
    private ObjectProperty<BitSet> bitsProperty;

    public PiecesIndicator() {
        this(0);
    }
    public PiecesIndicator(int count) {
        this(count, null);
    }

    public PiecesIndicator(int count, BitSet bits) {
        // focusTraversable is styleable through css. Calling setFocusTraversable
        // makes it look to css like the user set the value and css will not
        // override. Initializing focusTraversable by calling applyStyle with null
        // StyleOrigin ensures that css will be able to override the value.
        ((StyleableProperty<Boolean>) (WritableValue<Boolean>) focusTraversableProperty()).applyStyle(null, Boolean.FALSE);
        getStyleClass().setAll(DEFAULT_STYLE_CLASS);

        setCount(count);
        setBits(bits);
    }

    public void setCount(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("Count must be greater or equals zero!");
        }
        this.countProperty.setValue(count);
        setBits(getBits());
    }

    public int getCount() {
        return countProperty.get();
    }

    public void setBits(BitSet bits) {
        bitsProperty().setValue(bits);
    }

    public final BitSet getBits() {
        return bitsProperty != null ? bitsProperty.get() : null;
    }

    public final ObjectProperty<BitSet> bitsProperty() {
        if (bitsProperty == null) {
            bitsProperty = new ObjectPropertyBase<>() {
                @Override
                public Object getBean() {
                    return PiecesIndicator.this;
                }

                @Override
                public String getName() {
                    return "bits";
                }
            };
        }
        return bitsProperty;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected Skin<?> createDefaultSkin() {
        return new PiecesIndicatorSkin(this);
    }


    /**
     * Returns the initial focus traversable state of this control, for use
     * by the JavaFX CSS engine to correctly set its initial value. This method
     * is overridden as by default UI controls have focus traversable set to true,
     * but that is not appropriate for this control.
     */
    @Override
    protected Boolean getInitialFocusTraversable() {
        return Boolean.FALSE;
    }


    /***************************************************************************
     *                                                                         *
     * Accessibility handling                                                  *
     *                                                                         *
     **************************************************************************/

    /**
     * {@inheritDoc}
     */
    @Override
    public Object queryAccessibleAttribute(AccessibleAttribute attribute, Object... parameters) {
        return Orientation.HORIZONTAL;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public String getUserAgentStylesheet() {
        return PiecesIndicator.class.getResource("/ru/lukyanets/transmissionclient/ui/control/PiecesIndicator.css").toExternalForm();
    }
}
